package com.xiehua.task.monitor;

import akka.actor.ActorRef;
import com.xiehua.task.actor.EmailActor;
import com.xiehua.task.actor.cmd.Cmd;
import com.xiehua.task.job.PostOffice;
import com.xiehua.task.job.bucket.TopicBucket;
import com.xiehua.task.persistence.TaskPersistence;
import com.xiehua.task.persistence.rocks.RocksPersitence;
import com.xiehua.task.persistence.rocks.RocksPool;
import com.xiehua.task.persistence.rocks.XeihuaPersitence;
import com.xiehua.task.prop.XiehuaConfig;
import com.xiehua.task.redis.RedisTemplate;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.rocksdb.RocksDBException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;

import javax.mail.MessagingException;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

import static com.xiehua.task.actor.cmd.Cmd.CMD_SEND_EMAIL;
import static com.xiehua.task.monitor.Statistics.EMAIL_TYPE_COUNTING;
import static com.xiehua.task.prop.XiehuaConfig.SERVER_MONITOR_SWITCH;

public class Monitor extends Thread {

    private static final Logger logger = LoggerFactory.getLogger(Monitor.class);

    private List<Thread> monitoredThread; // 要监控的线程名

    private ActorRef emailActor;

    public Monitor(List<Thread> monitoredThread, ActorRef emailActor) {
        this.monitoredThread = monitoredThread;
        this.emailActor = emailActor;
    }

    public void run() {
        while (true) {
            try {
                Boolean flag = Boolean.parseBoolean(XiehuaConfig.getInstance().get(SERVER_MONITOR_SWITCH));
                if (flag) monitor();
                Thread.sleep(20000);
            } catch (Exception e) {
                logger.error("监控线程异常了", e);
                EmailActor.sendExceptionEmail(e, emailActor, ActorRef.noSender(), null);
            }
        }

    }

    /**
     * 监控主要逻辑
     */
    private void monitor() throws Exception {
        for (int i = 0; i < monitoredThread.size(); i++) {
            Thread.State state = monitoredThread.get(i).getState(); // 获得指定线程状态
            if (logger.isDebugEnabled()) logger.debug("线程:{} 的状态:{}", monitoredThread.get(i).getName(), monitoredThread.get(i).getState());
            //如果监控线程为终止状态,则重启监控线程
            if (Thread.State.TERMINATED.equals(state)) {
                EmailActor.sendExceptionEmail(new RuntimeException("Timmer线程挂了,请重启服务~"), emailActor, ActorRef.noSender(), null);
                return;
            }
            Jedis jedis = RedisTemplate.getJedis();
            PostOffice office = new PostOffice(jedis);
            LocalDateTime now = LocalDateTime.now();
            if (now.getMinute() == 0 && !office.existFlagEmalCount()) {
                GenericObjectPool<XeihuaPersitence> pool = RocksPool.getInstance();
                XeihuaPersitence persitence = pool.borrowObject();
                office.writeFlagEmailCount();//写入标志位
                //统计邮件
                TopicBucket topicBucket = new TopicBucket(jedis);
                Set<String> topics = topicBucket.queryTopics();
                if(topics != null && topics.size() > 0) topics.forEach(s ->{
                    Statistics statistics = new Statistics();
                    statistics.setTopic(s);
                    statistics.setType(EMAIL_TYPE_COUNTING);
                    statistics.setSelfFail(persitence.countfailJob(now.minusHours(1), now,s));
                    statistics.setSelfSuccess(persitence.countSuccessJob(now.minusHours(1), now,s));
                    statistics.setTaskFail(persitence.countfailJob(now.minusHours(1), now,null));
                    statistics.setTaskSuccess(persitence.countSuccessJob(now.minusHours(1), now,null));
                    Cmd<Statistics> cmd = new Cmd<>(CMD_SEND_EMAIL, statistics);
                    emailActor.tell(cmd, ActorRef.noSender());
                });
                pool.returnObject(persitence);
            }
            //释放资源
            jedis.close();
        }
    }

}